/*!  \file  CompileTime.cpp
 *	  \brief  
 * 
 *   \details   details
 *   \author    Yordan Madzhunkov German Research School for Simulation Sciences GmbH
 *   \version   1.0
 *   \date      07/07/2013 09:23:00 AM
 *   \copyright GNU Public License.
 */
#include <time.h>
#include <sys/times.h>
#include <unistd.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include "CompileTime.h"
using namespace std;
void CompileTime::setCompileTime(const char * date, const char * time) {
	struct tm c; memset(&c, 0, sizeof(c));
	c.tm_isdst = -1;
	if (parse(date, time, c.tm_year, c.tm_mon, c.tm_mday,	c.tm_hour, c.tm_min, 
		c.tm_sec) ) {
		c.tm_year -= 1900;	
		setCompileTime(mktime(&c));
	} else {
		cerr << "can't parse" << date << time << endl;
	}
}
CompileTime::CompileTime(){
	compileTime = 0;
	setCompileTime(__DATE__, __TIME__);
};
void CompileTime::setCompileTime(time_t newTime) {
	compileTime = difftime(newTime, compileTime) > 0 ? newTime : compileTime;
};
const char * months [] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", 
									"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
void CompileTime::printDateAndTime(char * s, time_t t) const {
	char * res = ctime(&t);
	memcpy(s, res, strlen(res) + 1);
}
time_t CompileTime::getDateAndTime(char const * s) const {
//Tue Jun 25 16:02:06 2013
	struct tm c;	memset(&c, 0, sizeof(c));
	c.tm_isdst = -1;
	char dayBuf[4]; char monthBuf[4];
	bool res = sscanf(s, "%s %s %d %d:%d:%d %d",dayBuf, monthBuf, &c.tm_mday,
		&c.tm_hour, &c.tm_min, &c.tm_sec, &c.tm_year) == 7;
	c.tm_mon = -1;
	for (int i = 0; i < 12; i++) 
		if (strncmp(monthBuf, months[i], 3) == 0) {
			c.tm_mon = i; break;
		}
	c.tm_year -= 1900;
	return res && c.tm_mon != -1 ? mktime(&c) : -1;
}

bool CompileTime::parse(const char * date, const char * time, int & year, 
		int & month, int & day, int & hour, int & minutes, int & seconds) const{
	bool res = true;
	month = -1; year = -1; day = -1;
	hour = -1; minutes = -1; seconds = -1;
	for (int i = 0; i < 12; i++) 
		if (strstr(date, months[i]) != 0) {
			if ( month == -1) month = i; else return false;
		}
	char monthBuf[12];
	res &= sscanf(date, "%s %d %d",monthBuf,     &day,    &year) == 3;
	res &= sscanf(time, "%d:%d:%d",&hour   , &minutes, &seconds) == 3;
	return res;
}
#include "UnitTester.h"
UNITTEST(TestCompileTime);
TestCompileTime::TestCompileTime() {
	setName 				("Test CompileTime");
	setDescription  	("Test CompileTime for correct bahaviour & memory allocation");
	setTestAuthor		("Yordan Madzhunkov");
	setDeveloperAuthor("Yordan Madzhunkov");
	setCompileTime    (__DATE__, __TIME__); // each class that inherits this one should also have this line.
};
bool TestCompileTime::test() const {
	CompileTime ct; 
	bool res = true;
	time_t t = 1372253845;
	char buf[30];
	ct.printDateAndTime(buf, t); // this one is correct
	//cout << "buf = " << buf << endl;
	// FOR Bulgaria time zone:
	res &= strcmp(buf, "Wed Jun 26 16:37:25 2013\n") == 0;
	time_t t2 = ct.getDateAndTime("Wed Jun 26 16:37:25 2013\n"); 
	// FOR GERMANY 
	/*
	res &= strcmp(buf, "Wed Jun 26 15:37:25 2013\n") == 0;
	time_t t2 = ct.getDateAndTime("Wed Jun 26 15:37:25 2013\n"); 
	*/

	res &= t == t2; 
	return res;
}
TestCompileTime testCompileTime;
